﻿namespace StockSharp.Algo.Indicators.Trend
{
	using System.ComponentModel;
	using System.Linq;

	/// <summary>
	/// Экспоненциальная скользящая средняя.
	/// </summary>
	[DisplayName("EMA")]
	[Description("Экспоненциальная скользящая средняя.")]
	public class ExponentialMovingAverage : LengthIndicator<decimal>
	{
		private decimal _multiplier;

		/// <summary>
		/// Создать <see cref="ExponentialMovingAverage"/>.
		/// </summary>
		public ExponentialMovingAverage()
			: base(typeof(decimal))
		{
			
		}

		/// <summary>
		/// Сбросить состояние индикатора на первоначальное. Метод вызывается каждый раз, когда меняются первоначальные настройки (например, длина периода).
		/// </summary>
		public override void Reset()
		{
			base.Reset();
			_multiplier = 2m / (Length + 1);
		}

		/// <summary>
		/// Обработать входное значение.
		/// </summary>
		/// <param name="input">Входное значение.</param>
		/// <returns>Результирующее значение.</returns>
		protected override decimal OnProcess(IIndicatorValue input)
		{
			var newValue = input.GetValue<decimal>();
			
			if (input.IsFinal)
				Buffer.Add(newValue);

			var lastValue = this.GetCurrentValue();

			if (!IsFormed)
				return lastValue;

			if (Buffer.Count == Length)
			{
				// Начальное значение - простая скользящая средняя.
				return Buffer.Sum() / Length;
			}
			else
			{
				if (input.IsFinal)
					Buffer.RemoveAt(0);

				return (newValue - lastValue) * _multiplier + lastValue;
			}
		}
	}
}